import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.ticker import MaxNLocator
from typing import List, Dict

def create_score_plot(df_report: pd.DataFrame) -> Figure:
    fig, ax = plt.subplots(figsize=(13, 7))
    top_classes = df_report.sort_values('平均成绩', ascending=False)
    sns.barplot(y='班级名称', x='平均成绩', data=top_classes, 
                hue='班级名称', palette='viridis', legend=False, ax=ax)
    ax.set_title('班级平均成绩排名')
    ax.xaxis.set_major_locator(MaxNLocator(integer=True))
    return fig

def create_attendance_plot(analysis_results: List[Dict]) -> Figure:
    fig, ax = plt.subplots(figsize=(7, 7))
    if analysis_results and analysis_results[0]['考勤统计']:
        pd.Series(analysis_results[0]['考勤统计']).plot(
            kind='pie', autopct='%1.1f%%', ax=ax)
        ax.set_title('典型班级考勤分布')
        ax.set_ylabel('')
    else:
        fig.delaxes(ax)
    return fig

def create_consumption_scatter(df_report: pd.DataFrame) -> Figure:
    fig, ax = plt.subplots(figsize=(13, 7))

    df_report['校区'] = df_report['班级名称'].str[0] + '校区'
    
    sns.scatterplot(
        x='日均消费(元)', 
        y='平均成绩', 
        data=df_report, 
        hue='校区',
        style='校区',
        s=150, 
        ax=ax,
        palette={'白校区': '#2ecc71', '东校区': '#e74c3c'},
        markers={'白校区': 'o', '东校区': 's'} 
    )
    
    ax.set_title('消费水平与成绩关系（按校区）')
    ax.xaxis.set_major_locator(MaxNLocator(integer=True))

    plt.legend(
        bbox_to_anchor=(1, 0.5), 
        loc='center left',
        title='校区'
    )

    sns.regplot(
        x='日均消费(元)', 
        y='平均成绩', 
        data=df_report,
        scatter=False, 
        color='grey',
        line_kws={'linestyle': '--', 'alpha': 0.5},
        ax=ax
    )
    return fig

def create_campus_boxplot(df_report: pd.DataFrame) -> Figure:
    fig, ax = plt.subplots(figsize=(13, 7))
    df_report['校区'] = df_report['班级名称'].str[0] + '校区'
    sns.boxplot(x='校区', y='平均成绩', data=df_report, ax=ax)
    ax.set_title('校区成绩对比')
    return fig